﻿using Aliphant.Common;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;

namespace Aliphant.ChatAI.Tools
{
    public class SharesAPI
    {
        /// <summary>
        /// 获取K线数据
        /// </summary>
        /// <param name="code">股票代码</param>
        /// <param name="days">天数</param>
        public static async Task<string[]> GetKLinesAsync(string code, int days)
        {
            if (string.IsNullOrEmpty(code))
            {
                return [];
            }

            string secid = code.StartsWith("6") ? "1." + code : "0." + code;

            string baseUrl = "http://push2his.eastmoney.com/api/qt/stock/kline/get";
            var parameters = new Dictionary<string, string>
            {
                { "fields1", "f1,f2,f3,f4,f5,f6" },
                { "fields2", "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116" },
                { "ut", "7eea3edcaed734bea9cbfc24409ed989" },
                { "klt", "101" },
                { "fqt", "0" },
                { "secid", secid },
                { "beg", DateTime.Now.AddDays(-days).ToString("yyyyMMdd") },
                { "end", DateTime.Now.ToString("yyyyMMdd") },
                { "_", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString() },
            };

            string fullUrl = $"{baseUrl}?{BuildQueryString(parameters)}";

            try
            {
                var content = await HttpGetAsync(fullUrl);
                JObject json = JObject.Parse(content);
                if (json == null)
                {
                    return [];
                }

                var data = json["data"];
                var klines = data?["klines"];
                var name = data?["name"];

                List<string> klineArr = JsonConvert.DeserializeObject<List<string>>(json["data"]?["klines"]?.ToString() ?? "[]") ?? [];
                klineArr.Insert(0, name?.ToString() ?? "");

                return klineArr.ToArray();
            }
            catch
            {

            }
            return [];
        }

        /// <summary>
        /// 获取主力资金流向
        /// </summary>
        /// <param name="code"></param>
        /// <param name="days"></param>
        /// <returns></returns>
        public static async Task<string[]> GetMainCapitalAsync(string code, int days)
        {
            if (string.IsNullOrEmpty(code))
            {
                return [];
            }

            string secid = code.StartsWith("6") ? "1." + code : "0." + code;

            string baseUrl = "https://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get";
            var parameters = new Dictionary<string, string>
            {
                { "lmt", "0" },
                { "klt", "1" },
                { "fields1", "f1,f2,f3,f7" },
                { "fields2", "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63,f64,f65" },
                { "ut", "b2884a393a59ad64002292a3e90d46a5" },
                { "secid", secid },
            };

            string fullUrl = $"{baseUrl}?{BuildQueryString(parameters)}";

            try
            {
                var content = await HttpGetAsync(fullUrl);
                JObject json = JObject.Parse(content);
                if (json == null)
                {
                    return [];
                }

                var data = json["data"];
                var klines = data?["klines"];
                var name = data?["name"];

                List<string> klineArr = JsonConvert.DeserializeObject<List<string>>(json["data"]?["klines"]?.ToString() ?? "[]") ?? [];
                klineArr.RemoveRange(0, klineArr.Count - days);
                klineArr.Insert(0, name?.ToString() ?? "");
                return [.. klineArr];
            }
            catch
            {

            }
            return [];
        }

        /// <summary>
        /// 获取当日分时数据
        /// </summary>
        /// <param name="code"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public static async Task<string[]> GetTimeSharingAsync(string code, int time)
        {
            if (string.IsNullOrEmpty(code))
            {
                return [];
            }

            string secid = code.StartsWith("6") ? "1." + code : "0." + code;

            //if (time == 1)
            //{
            //    string baseUrl = "https://push2his.eastmoney.com/api/qt/stock/trends2/get";
            //    var parameters = new Dictionary<string, string>
            //    {
            //        { "fields1", "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13" },
            //        { "fields2", "f51,f52,f53,f54,f55,f56,f57,f58" },
            //        { "ut", "7eea3edcaed734bea9cbfc24409ed989" },
            //        { "ndays", "5" },
            //        { "iscr", "0" },
            //        { "secid", secid },
            //        { "_", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString() },
            //    };

            //    string fullUrl = $"{baseUrl}?{BuildQueryString(parameters)}";

            //    var content = await HttpGetAsync(fullUrl);
            //    JObject json = JObject.Parse(content);
            //    if (json == null) return [];

            //    var data = json["data"];
            //    var klines = data?["trends"];
            //    var name = data?["name"];

            //    List<string> klineArr = JsonConvert.DeserializeObject<List<string>>(json["data"]?["trends"]?.ToString() ?? "[]") ?? [];
            //    klineArr.Insert(0, name?.ToString() ?? "");
            //    return [.. klineArr];
            //}
            //else
            //{
            string baseUrl = "http://push2his.eastmoney.com/api/qt/stock/kline/get";
            var parameters = new Dictionary<string, string>
                {
                    { "fields1", "f1,f2,f3,f4,f5,f6" },
                    { "fields2", "f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61" },
                    { "ut", "7eea3edcaed734bea9cbfc24409ed989" },
                    { "klt", time.ToString() },
                    { "fqt", "0" },
                    { "secid", secid },
                    { "beg", DateTime.Now.AddDays(-2).ToString("yyyyMMdd") },
                    { "end", DateTime.Now.ToString("yyyyMMdd") },
                    { "_", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString() },
                };

            string fullUrl = $"{baseUrl}?{BuildQueryString(parameters)}";

            var content = await HttpGetAsync(fullUrl);
            JObject json = JObject.Parse(content);
            if (json == null) return [];

            var data = json["data"];
            var klines = data?["klines"];
            var name = data?["name"];

            List<string> klineArr = JsonConvert.DeserializeObject<List<string>>(json["data"]?["klines"]?.ToString() ?? "[]") ?? [];
            klineArr.Insert(0, name?.ToString() ?? "");
            return [.. klineArr];
            //}
        }

        /// <summary>
        /// 获取资金流向
        /// </summary>
        /// <param name="time">日档位: 今日/三日/五日/十日</param>
        /// <returns></returns>
        public static async Task<string[]> GetCpitalFlowAsync(int time)
        {
            string baseUrl = "http://push2.eastmoney.com/api/qt/clist/get";

            string fid = "";
            string fields = "";

            switch (time)
            {
                case 0:
                    fid = "f62";
                    fields = "f12,f14,f2,f3,f62,f184,f66,f69,f72,f75,f78,f81,f84,f87,f204,f205,f124";
                    break;
                case 3:
                    fid = "f267";
                    fields = "f12,f14,f2,f127,f267,f268,f269,f270,f271,f272,f273,f274,f275,f276,f257,f258,f124";
                    break;
                case 5:
                    fid = "f164";
                    fields = "f12,f14,f2,f109,f164,f165,f166,f167,f168,f169,f170,f171,f172,f173,f257,f258,f124";
                    break;
                case 10:
                    fid = "f174";
                    fields = "f12,f14,f2,f160,f174,f175,f176,f177,f178,f179,f180,f181,f182,f183,f260,f261,f124";
                    break;
            }

            var parameters = new Dictionary<string, string>
            {
                { "fid", fid },
                { "fields", fields },
                { "po", "1" },
                { "pz", "50" },
                { "pn", "1" },
                { "np", "1" },
                { "fltt", "2" },
                { "invt", "2" },
                { "ut", "b2884a393a59ad64002292a3e90d46a5" },
                { "fs", "m:0+t:6+f:!2,m:0+t:13+f:!2,m:0+t:80+f:!2,m:1+t:2+f:!2,m:1+t:23+f:!2,m:0+t:7+f:!2,m:1+t:3+f:!2" },
            };

            string fullUrl = $"{baseUrl}?{BuildQueryString(parameters)}";

            try
            {
                var content = await HttpGetAsync(fullUrl);
                JObject json = JObject.Parse(content);
                if (json == null)
                {
                    return [];
                }

                var data = json["data"];
                var diff = data?["diff"];

                List<string> sharArr = JsonConvert.DeserializeObject<List<string>>(json["data"]?["diff"]?.ToString() ?? "[]") ?? [];
                return [.. sharArr];
            }
            catch
            {

            }
            return [];
        }

        /// <summary>
        /// 获取股票实时数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static async Task<string[]> QueryCurrentDataAsync(string code)
        {
            string url = "https://qt.gtimg.cn/q=" + code;

            try
            {
                var content = await TencentHttpGetAsync(url);
                content = content.Split('=')[1].Trim('"');
                var paramArr = content.Split("~");
                return paramArr;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }

            return [];
        }

        /// <summary>
        /// 搜索股票
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static async Task<string> SearchStockCode(string key)
        {
            string url = "https://smartbox.gtimg.cn/s3/?v=2&t=all&c=1&q=" + key;
            try
            {
                string content = await TencentHttpGetAsync(url);
                content = content.Split('=')[1].Trim('"');
                var paramArr = content.Split("~");

                string cont = paramArr[0];
                string code = paramArr[1];
                return cont + code;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }

        /// <summary>
        /// 创建请求文本
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static string BuildQueryString(Dictionary<string, string> parameters)
        {
            using var content = new FormUrlEncodedContent(parameters);
            return content.ReadAsStringAsync().Result;
        }

        private static async Task<string> HttpGetAsync(string url)
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            try
            {
                var response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    return content;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }

        /// <summary>
        /// 腾讯财经HTTP请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private static async Task<string> TencentHttpGetAsync(string url)
        {
            HttpClient client = new HttpClient();
            try
            {
                var response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    byte[] buffer = await response.Content.ReadAsByteArrayAsync();
                    var content = Encoding.GetEncoding("GBK").GetString(buffer);
                    return content;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
            return string.Empty;
        }
    }
}
